home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Python / dynload_next.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-03  |  4.3 KB  |  169 lines

  1. /* Support for dynamic loading of extension modules */
  2.  
  3. #include "Python.h"
  4. #include "importdl.h"
  5.  
  6.  
  7. #ifdef WITH_DYLD
  8.  
  9. #define USE_DYLD
  10.  
  11. #include <mach-o/dyld.h>
  12.  
  13. #else /* WITH_DYLD */
  14.  
  15. #define USE_RLD
  16. /* Define this to 1 if you want be able to load ObjC modules as well:
  17.    it switches between two different way of loading modules on the NeXT,
  18.    one that directly interfaces with the dynamic loader (rld_load(), which
  19.    does not correctly load ObjC object files), and another that uses the
  20.    ObjC runtime (objc_loadModules()) to do the job.
  21.    You'll have to add ``-ObjC'' to the compiler flags if you set this to 1.
  22. */
  23. #define HANDLE_OBJC_MODULES 1
  24. #if HANDLE_OBJC_MODULES
  25. #include <objc/Object.h>
  26. #include <objc/objc-load.h>
  27. #endif
  28.  
  29. #include <mach-o/rld.h>
  30.  
  31. #endif /* WITH_DYLD */
  32.  
  33.  
  34. const struct filedescr _PyImport_DynLoadFiletab[] = {
  35.     {".so", "rb", C_EXTENSION},
  36.     {"module.so", "rb", C_EXTENSION},
  37.     {0, 0}
  38. };
  39.  
  40. dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname,
  41.                     const char *pathname, FILE *fp)
  42. {
  43.     dl_funcptr p = NULL;
  44.     char funcname[258];
  45.  
  46.     sprintf(funcname, "_init%.200s", shortname);
  47.  
  48. #ifdef USE_RLD
  49.     {
  50.         NXStream *errorStream;
  51.         struct mach_header *new_header;
  52.         const char *filenames[2];
  53.         long ret;
  54.         unsigned long ptr;
  55.  
  56.         errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  57.         filenames[0] = pathname;
  58.         filenames[1] = NULL;
  59.  
  60. #if HANDLE_OBJC_MODULES
  61.  
  62. /* The following very bogus line of code ensures that
  63.    objc_msgSend, etc are linked into the binary.  Without
  64.    it, dynamic loading of a module that includes objective-c
  65.    method calls will fail with "undefined symbol _objc_msgSend()".
  66.    This remains true even in the presence of the -ObjC flag
  67.    to the compiler
  68. */
  69.  
  70.         [Object name];
  71.  
  72. /* objc_loadModules() dynamically loads the object files
  73.    indicated by the paths in filenames.  If there are any
  74.    errors generated during loading -- typically due to the
  75.    inability to find particular symbols -- an error message
  76.    will be written to errorStream.
  77.    It returns 0 if the module is successfully loaded, 1
  78.    otherwise.
  79. */
  80.  
  81.         ret = !objc_loadModules(filenames, errorStream,
  82.                     NULL, &new_header, NULL);
  83.  
  84. #else /* !HANDLE_OBJC_MODULES */
  85.  
  86.         ret = rld_load(errorStream, &new_header, 
  87.                 filenames, NULL);
  88.  
  89. #endif /* HANDLE_OBJC_MODULES */
  90.  
  91.         /* extract the error messages for the exception */
  92.         if(!ret) {
  93.             char *streamBuf;
  94.             int len, maxLen;
  95.  
  96.             NXPutc(errorStream, (char)0);
  97.  
  98.             NXGetMemoryBuffer(errorStream,
  99.                 &streamBuf, &len, &maxLen);
  100.             PyErr_SetString(PyExc_ImportError, streamBuf);
  101.         }
  102.  
  103.         if(ret && rld_lookup(errorStream, funcname, &ptr))
  104.             p = (dl_funcptr) ptr;
  105.  
  106.         NXCloseMemory(errorStream, NX_FREEBUFFER);
  107.  
  108.         if(!ret)
  109.             return NULL;
  110.     }
  111. #endif /* USE_RLD */
  112. #ifdef USE_DYLD
  113.     /* This is also NeXT-specific. However, frameworks (the new style
  114.     of shared library) and rld() can't be used in the same program;
  115.     instead, you have to use dyld, which is mostly unimplemented. */
  116.     {
  117.         NSObjectFileImageReturnCode rc;
  118.         NSObjectFileImage image;
  119.         NSModule newModule;
  120.         NSSymbol theSym;
  121.         void *symaddr;
  122.         const char *errString;
  123.     
  124.         rc = NSCreateObjectFileImageFromFile(pathname, &image);
  125.         switch(rc) {
  126.             default:
  127.             case NSObjectFileImageFailure:
  128.             NSObjectFileImageFormat:
  129.             /* for these a message is printed on stderr by dyld */
  130.             errString = "Can't create object file image";
  131.             break;
  132.             case NSObjectFileImageSuccess:
  133.             errString = NULL;
  134.             break;
  135.             case NSObjectFileImageInappropriateFile:
  136.             errString = "Inappropriate file type for dynamic loading";
  137.             break;
  138.             case NSObjectFileImageArch:
  139.             errString = "Wrong CPU type in object file";
  140.             break;
  141.             NSObjectFileImageAccess:
  142.             errString = "Can't read object file (no access)";
  143.             break;
  144.         }
  145.         if (errString == NULL) {
  146.             newModule = NSLinkModule(image, pathname, TRUE);
  147.             if (!newModule)
  148.                 errString = "Failure linking new module";
  149.         }
  150.         if (errString != NULL) {
  151.             PyErr_SetString(PyExc_ImportError, errString);
  152.             return NULL;
  153.         }
  154.         if (!NSIsSymbolNameDefined(funcname)) {
  155.             /* UnlinkModule() isn't implimented in current versions, but calling it does no harm */
  156.             NSUnLinkModule(newModule, FALSE);
  157.             PyErr_Format(PyExc_ImportError,
  158.                      "Loaded module does not contain symbol %.200s",
  159.                      funcname);
  160.             return NULL;
  161.         }
  162.         theSym = NSLookupAndBindSymbol(funcname);
  163.         p = (dl_funcptr)NSAddressOfSymbol(theSym);
  164.      }
  165. #endif /* USE_DYLD */
  166.  
  167.     return p;
  168. }
  169.